package com.ylyq.ylxx.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ylyq.ylxx.constants.AccountConstant;
import com.ylyq.ylxx.context.FilterContextHandler;
import com.ylyq.ylxx.entity.YlyqBudget;
import com.ylyq.ylxx.entity.YlyqGroupInfo;
import com.ylyq.ylxx.entity.YlyqPlanBidBudget;
import com.ylyq.ylxx.model.ResponseData;
import com.ylyq.ylxx.model.bean.*;
import com.ylyq.ylxx.model.request.*;
import com.ylyq.ylxx.service.*;
import com.ylyq.ylxx.util.HttpClientUtils;
import com.ylyq.ylxx.util.Tools;
import org.apache.shiro.authc.Account;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName OceanegineServiceImpl
 * @Description TODO
 * @Author xiaweichao
 * @Date 2020/6/24 16:40
 * @Version 1.0
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class OceanegineServiceImpl implements IOceanegineService {

    @Autowired
    private IYlyqGroupInfoService iYlyqGroupInfoService;
    @Autowired
    private IOceaneginePlanService iOceaneginePlanService;
    @Autowired
    private IOceanegineReportService iOceanegineReportService;
    @Autowired
    private IYlyqPlanBidBudgetService iYlyqPlanBidBudgetService;
    @Autowired
    private IYlyqBudgetService iYlyqBudgetService;

    @Override
    public ResponseData getUserInfoByToken() {

        // 请求地址
        String open_api_url_prefix = AccountConstant.OCEANENGINE_URL + "2/";
        String uri = "user/info/";

        // 构造请求
        Map<String, String> headers = new HashMap<>();
        headers.put("Access-Token", FilterContextHandler.getOceaneToken());
        String result = HttpClientUtils.get(open_api_url_prefix + uri, "", headers);

        JSONObject jsonObject = JSONObject.parseObject(result);
        OceanengineUserInfoByToken oceanengineUserInfoByToken = JSONObject.toJavaObject(jsonObject, OceanengineUserInfoByToken.class);


        return new ResponseData(ResponseData.Result.SUCCESS, oceanengineUserInfoByToken);
    }

    @Override
    public ResponseData getUserInfo() {
        // 请求地址
        String open_api_url_prefix = AccountConstant.OCEANENGINE_URL;
        String uri = "oauth2/advertiser/get/";

        // 请求参数
        Map<String, Object> data = new HashMap() {
            {
                put("app_id", AccountConstant.OCEANENGINE_APPID);
                put("secret", AccountConstant.OCEANENGINE_SECRET);
                put("access_token", FilterContextHandler.getOceaneToken());
            }
        };

        String result = HttpClientUtils.get(open_api_url_prefix + uri, JSONObject.toJSONString(data));

        JSONObject jsonObject = JSONObject.parseObject(result);
        OceanengineAccount oceanengineAccount = JSONObject.toJavaObject(jsonObject, OceanengineAccount.class);
        if (null != oceanengineAccount) {
            List<OceanengineAccount.OceanengineAccountDataBean.OceanengineAccountListBean> list = oceanengineAccount.getData().getList();
            if (null != list) {
                for (OceanengineAccount.OceanengineAccountDataBean.OceanengineAccountListBean temp : list) {
                    if (temp.getAdvertiser_role() == 2) {//广告主角色，1-普通广告主，2-账号管家，3-一级代理商，4-二级代理商
                        OceanengineAccountManagerInfo advertiserIdbyAID = getAdvertiserIdbyAID(temp.getAdvertiser_id());
                        if (null != advertiserIdbyAID)
                            temp.setList(advertiserIdbyAID.getData().getList());
                    }
                }
            }
        }
        return new ResponseData(ResponseData.Result.SUCCESS, oceanengineAccount);
    }

    /**
     * @return void
     * @Author xiaweichao
     * @Description //TODO  * @Date 14:42 2020/7/8
     * @Param [advertiser_id:账户管家id]
     **/
    public OceanengineAccountManagerInfo getAdvertiserIdbyAID(Long advertiser_id) {
        // 请求地址
        String open_api_url_prefix = AccountConstant.OCEANENGINE_URL;
        String uri = "2/majordomo/advertiser/select/";

        Map<String, String> headers = new HashMap<>();
        headers.put("Access-Token", FilterContextHandler.getOceaneToken());

        // 请求参数
        Map<String, Object> data = new HashMap() {
            {
                put("advertiser_id", advertiser_id);
            }
        };

        String result = HttpClientUtils.get(open_api_url_prefix + uri, JSONObject.toJSONString(data), headers);

        JSONObject jsonObject = JSONObject.parseObject(result);
        OceanengineAccountManagerInfo oceanengineAccount = JSONObject.toJavaObject(jsonObject, OceanengineAccountManagerInfo.class);
        return oceanengineAccount;
    }

    @Override
    public OceanengineGetBalance getBalance(GetBalanceRequest getBalanceRequest) {
        // 请求地址
        String open_api_url_prefix = AccountConstant.OCEANENGINE_URL + "2/";
        String uri = "advertiser/fund/get/";

        // 构造请求
        Map<String, String> headers = new HashMap<>();
        headers.put("Access-Token", FilterContextHandler.getOceaneToken());
        String result = HttpClientUtils.get(open_api_url_prefix + uri, JSONObject.toJSON(getBalanceRequest).toString(), headers);

        JSONObject jsonObject = JSONObject.parseObject(result);
        OceanengineGetBalance oceanengineAccount = JSONObject.toJavaObject(jsonObject, OceanengineGetBalance.class);

        OceanengineDailyStat dailyStat = getDailyStat(getBalanceRequest);
        try {
            if (null != dailyStat.getData().getList() && !dailyStat.getData().getList().isEmpty())
                oceanengineAccount.getData().setToday_cosr(dailyStat.getData().getList().get(0).getBalance() - oceanengineAccount.getData().getBalance());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return oceanengineAccount;
    }

    @Override
    public OceanengineDailyStat getDailyStat(GetBalanceRequest getBalanceRequest) {
        // 请求地址
        String open_api_url_prefix = AccountConstant.OCEANENGINE_URL + "2/";
        String uri = "advertiser/fund/daily_stat/";

        // 构造请求
        Map<String, String> headers = new HashMap<>();
        headers.put("Access-Token", FilterContextHandler.getOceaneToken());
        String result = HttpClientUtils.get(open_api_url_prefix + uri, JSONObject.toJSON(getBalanceRequest).toString(), headers);

        JSONObject jsonObject = JSONObject.parseObject(result);
        OceanengineDailyStat oceanengineAccount = JSONObject.toJavaObject(jsonObject, OceanengineDailyStat.class);

        return oceanengineAccount;
    }

    @Override
    public GetAccount getAccountDay(GetAccountDayRequest getAccountDayRequest) {
        // 请求地址
        String open_api_url_prefix = AccountConstant.OCEANENGINE_URL + "2/";
        String uri = "advertiser/budget/get/";

        // 构造请求
        Map<String, String> headers = new HashMap<>();
        headers.put("Access-Token", FilterContextHandler.getOceaneToken());
        String result = HttpClientUtils.get(open_api_url_prefix + uri, JSONObject.toJSON(getAccountDayRequest).toString(), headers);

        JSONObject jsonObject = JSONObject.parseObject(result);
        GetAccount oceanengineAccount = JSONObject.toJavaObject(jsonObject, GetAccount.class);

        return oceanengineAccount;
    }

    @Override
    public UpdateAccountBudget updateAccount(UpdateAccountRequest updateAccountRequest) {
        // 请求地址
        String open_api_url_prefix = AccountConstant.OCEANENGINE_URL + "2/";
        String uri = "advertiser/update/budget/";

        // 构造请求
        Map<String, String> headers = new HashMap<>();
        headers.put("Access-Token", FilterContextHandler.getOceaneToken());
        String result = HttpClientUtils.post(open_api_url_prefix + uri, JSONObject.toJSON(updateAccountRequest).toString(), headers);

        JSONObject jsonObject = JSONObject.parseObject(result);
        UpdateAccountBudget oceanengineAccount = JSONObject.toJavaObject(jsonObject, UpdateAccountBudget.class);

        return oceanengineAccount;
    }

    @Override
    public ResponseData setAccount(SetAccountRequest setAccountRequest) {

        if (setAccountRequest.getBudgetDay() == null) {
            return new ResponseData(ResponseData.Result.FAIL, "未填日预算");
        }
        if (setAccountRequest.getBudgetWeek() == null) {
            return new ResponseData(ResponseData.Result.FAIL, "未填周预算");
        }
        if (setAccountRequest.getBudgetTotal() == null) {
            return new ResponseData(ResponseData.Result.FAIL, "未填总预算");
        }
        if (setAccountRequest.getBudgetDay().doubleValue() > setAccountRequest.getBudgetTotal().doubleValue() || setAccountRequest.getBudgetDay().doubleValue() > setAccountRequest.getBudgetWeek().doubleValue()) {
            return new ResponseData(ResponseData.Result.FAIL, "日预算不能大于周预算或总预算");
        }
        if (setAccountRequest.getBudgetWeek().doubleValue() > setAccountRequest.getBudgetTotal().doubleValue()) {
            return new ResponseData(ResponseData.Result.FAIL, "周预算不能大于总预算");
        }


        QueryWrapper<YlyqBudget> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("advertise_id", setAccountRequest.getAdvertiser_id());
        YlyqBudget ylyqBudget = iYlyqBudgetService.getOne(queryWrapper);

        if (ylyqBudget == null) {
            ylyqBudget = new YlyqBudget();
        }

        if(ylyqBudget.getBudgetDay()!=null&&ylyqBudget.getBudgetDay().doubleValue()==setAccountRequest.getBudgetDay().doubleValue()){//日预算没有修改，就不调巨量接口
            ylyqBudget.setAdvertiseId(setAccountRequest.getAdvertiser_id());
            ylyqBudget.setUserId(FilterContextHandler.getUserID());
            ylyqBudget.setBudgetDay(setAccountRequest.getBudgetDay());
            ylyqBudget.setBudgetModeDay(setAccountRequest.getBudgetDay() == null ? "BUDGET_MODE_INFINITE" : "BUDGET_MODE_DAY");//"BUDGET_MODE_INFINITE"为不限, "BUDGET_MODE_DAY"为日预算"
            ylyqBudget.setBudgetWeek(setAccountRequest.getBudgetWeek());
            ylyqBudget.setBudgetModeWeek(setAccountRequest.getBudgetWeek() == null ? "BUDGET_MODE_INFINITE" : "BUDGET_MODE_DAY");
            ylyqBudget.setBudgetTotal(setAccountRequest.getBudgetTotal());
            ylyqBudget.setBudgetModeTotal(setAccountRequest.getBudget_mode_total());
            iYlyqBudgetService.saveOrUpdate(ylyqBudget);
            return new ResponseData(ResponseData.Result.SUCCESS);
        }else {
            ylyqBudget.setAdvertiseId(setAccountRequest.getAdvertiser_id());
            ylyqBudget.setUserId(FilterContextHandler.getUserID());
            ylyqBudget.setBudgetDay(setAccountRequest.getBudgetDay());
            ylyqBudget.setBudgetModeDay(setAccountRequest.getBudgetDay() == null ? "BUDGET_MODE_INFINITE" : "BUDGET_MODE_DAY");//"BUDGET_MODE_INFINITE"为不限, "BUDGET_MODE_DAY"为日预算"
            ylyqBudget.setBudgetWeek(setAccountRequest.getBudgetWeek());
            ylyqBudget.setBudgetModeWeek(setAccountRequest.getBudgetWeek() == null ? "BUDGET_MODE_INFINITE" : "BUDGET_MODE_DAY");
            ylyqBudget.setBudgetTotal(setAccountRequest.getBudgetTotal());
            ylyqBudget.setBudgetModeTotal(setAccountRequest.getBudget_mode_total());
            iYlyqBudgetService.saveOrUpdate(ylyqBudget);
            UpdateAccountRequest updateAccountRequest = new UpdateAccountRequest();
            updateAccountRequest.setAdvertiser_id(setAccountRequest.getAdvertiser_id());
            updateAccountRequest.setBudget(setAccountRequest.getBudgetDay());
            updateAccountRequest.setBudget_mode(setAccountRequest.getBudgetDay() == null ? "BUDGET_MODE_INFINITE" : "BUDGET_MODE_DAY");//"BUDGET_MODE_INFINITE"为不限, "BUDGET_MODE_DAY"为日预算"
            UpdateAccountBudget updateAccount = updateAccount(updateAccountRequest);
            if (updateAccount.getCode() == AccountConstant.SUCCESS)
                return new ResponseData(ResponseData.Result.SUCCESS);
            else
                return new ResponseData(ResponseData.Result.FAIL,updateAccount.getMessage());
        }
    }

    @Override
    public IsSetAccount isSetAccount(IsSetAccountRequest issetAccountRequest) {
        QueryWrapper<YlyqBudget> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("advertise_id", issetAccountRequest.getAdvertiser_id());
        YlyqBudget ylyqBudget = iYlyqBudgetService.getOne(queryWrapper);
        if (ylyqBudget != null && ylyqBudget.getBudgetTotal() != null && ylyqBudget.getBudgetTotal() > 0) {
            return new IsSetAccount(0);
        }
        return new IsSetAccount(1);
    }

    @Override
    public YlyqBudgetResponse getAccount(GetAccountRequest getAccountDayRequest) {
        YlyqBudgetResponse ylyqBudgetResponse = new YlyqBudgetResponse();
        QueryWrapper<YlyqBudget> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("advertise_id", getAccountDayRequest.getAdvertiser_id());
        List<YlyqBudget> listBudget = iYlyqBudgetService.list(queryWrapper);
        if (listBudget == null || listBudget.isEmpty()) {
            return null;
        }

        int budgetSize = listBudget.size();
        if (budgetSize > 1) {//有重复的，删除，只留一条
            List<String> removeIds = new ArrayList<>();
            for (int i = budgetSize - 1; i > 0; i--) {
                removeIds.add(listBudget.get(i).getId());
                listBudget.remove(i);
            }
            iYlyqBudgetService.removeByIds(removeIds);
        }

        GetAccount accountDay = getAccountDay(new GetAccountDayRequest(new Long[]{getAccountDayRequest.getAdvertiser_id()}));
        if (accountDay != null && accountDay.getCode() == AccountConstant.SUCCESS) {

            YlyqBudget ylyqBudget = listBudget.get(0);
            if (!accountDay.getData().getList().get(0).getBudget_mode().equals(ylyqBudget.getBudgetModeDay())) {//用户在巨量手动修改了预算情况
                ylyqBudget.setBudgetModeDay(accountDay.getData().getList().get(0).getBudget_mode());
            }

            if (accountDay.getData().getList().get(0).getBudget().doubleValue() != ylyqBudget.getBudgetDay().doubleValue()) {//用户在巨量手动修改了预算情况
                ylyqBudget.setBudgetDay(accountDay.getData().getList().get(0).getBudget());
                if (accountDay.getData().getList().get(0).getBudget().doubleValue() > ylyqBudget.getBudgetWeek().doubleValue()) {
                    ylyqBudget.setBudgetWeek(accountDay.getData().getList().get(0).getBudget());
                    if (accountDay.getData().getList().get(0).getBudget().doubleValue() > ylyqBudget.getBudgetTotal().doubleValue()) {
                        ylyqBudget.setBudgetTotal(accountDay.getData().getList().get(0).getBudget());
                    }
                }
                iYlyqBudgetService.updateById(ylyqBudget);
            }

            ylyqBudgetResponse.setBudgetTotal(ylyqBudget.getBudgetTotal());
            ylyqBudgetResponse.setBudgetWeek(ylyqBudget.getBudgetWeek());
            ylyqBudgetResponse.setBudgetDay(ylyqBudget.getBudgetDay());
            ylyqBudgetResponse.setBudgetModeDay(ylyqBudget.getBudgetModeDay());
            ylyqBudgetResponse.setBudgetModeWeek(ylyqBudget.getBudgetModeWeek());
            ylyqBudgetResponse.setBudgetModeTotal(ylyqBudget.getBudgetModeTotal());
        }
        return ylyqBudgetResponse;
    }

    @Override
    public GroupReportInfo getManagerData(GetManagerDataRequest getManagerDataRequest) {
        GroupReportInfo result = getManagerDataTemplate(getManagerDataRequest);
        if (result == null)
            return null;

        int day = Tools.getDayFromdateToEndDate(getManagerDataRequest.getStart_date(), getManagerDataRequest.getEnd_date()) + 1;//左闭右闭，需要加1
        String startDate = Tools.getDatelaterDay(getManagerDataRequest.getStart_date(), day);
        String endDate = Tools.getDatelaterDay(getManagerDataRequest.getEnd_date(), day);

        getManagerDataRequest.setStart_date(startDate);
        getManagerDataRequest.setEnd_date(endDate);
        GroupReportInfo resultLater = getManagerDataTemplate(getManagerDataRequest);
        if (resultLater == null)
            return result;

        result.setRoiRat(resultLater.getRoi().doubleValue() == 0 ? null : (result.getRoi() - resultLater.getRoi()) / resultLater.getRoi());
        result.setConvertRat(resultLater.getConvert().longValue() == 0 ? null : (result.getConvert() - resultLater.getConvert()) * 1.0 / resultLater.getConvert());
        result.setCostRat(resultLater.getCost().doubleValue() == 0 ? null : (result.getCost() - resultLater.getCost()) / resultLater.getCost());
        result.setConvert_costRat(resultLater.getConvert_cost().doubleValue() == 0 ? null : (result.getConvert_cost() - resultLater.getConvert_cost()) / resultLater.getConvert_cost());
        result.setShowRat(resultLater.getShow().longValue() == 0 ? null : (result.getShow() - resultLater.getShow()) * 1.0 / resultLater.getShow());

        return result;
    }

    public GroupReportInfo getManagerDataTemplate(GetManagerDataRequest getManagerDataRequest) {
        List<GroupReportInfo> managerDataList = getManagerDataListTemplate(getManagerDataRequest);
        if (managerDataList == null || managerDataList.isEmpty())
            return null;
        GroupReportInfo result = new GroupReportInfo();
        double cost = 0;
        long convert = 0;
        long show = 0;
        double priceForm = 0;
        double convert_cost = 0;
        double ctr = 0;
        double convert_rate = 0;
        for (GroupReportInfo temp : managerDataList) {
            cost += temp.getCost();
            convert += temp.getConvert();
            show += temp.getShow();
            priceForm += temp.getPriceForm();
            convert_cost += temp.getConvert_cost();
            ctr += temp.getCtr();
            convert_rate += temp.getConvert_rate();
        }
        result.setConvert(convert);
        result.setShow(show);
        result.setCost(cost);
        result.setRoi(cost == 0 ? 0 : priceForm * convert / cost);
        result.setConvert_cost(convert_cost / managerDataList.size());
        result.setCtr(ctr / managerDataList.size());
        result.setConvert_rate(convert_rate / managerDataList.size());
        result.setPriceForm(priceForm / managerDataList.size());
        return result;
    }

    @Override
    public ManagerDataListPage getManagerDataListPage(GetManagerDataRequest getManagerDataRequest) {
        if (null == getManagerDataRequest.getPage()) {
            getManagerDataRequest.setPage(1);
        }
        if (null == getManagerDataRequest.getPageSize()) {
            getManagerDataRequest.setPageSize(10);
        }
        List<GroupReportInfo> result = getManagerDataListTemplate(getManagerDataRequest);
        if (null == result)
            return null;

        int day = Tools.getDayFromdateToEndDate(getManagerDataRequest.getStart_date(), getManagerDataRequest.getEnd_date()) + 1;//左闭右闭，需要加1
        String startDate = Tools.getDatelaterDay(getManagerDataRequest.getStart_date(), day);
        String endDate = Tools.getDatelaterDay(getManagerDataRequest.getEnd_date(), day);

        getManagerDataRequest.setStart_date(startDate);
        getManagerDataRequest.setEnd_date(endDate);

        List<GroupReportInfo> resultLater = getManagerDataListTemplate(getManagerDataRequest);
        if (null == resultLater || resultLater.isEmpty())
            return new ManagerDataListPage(result.subList(getManagerDataRequest.getPageSize() * (getManagerDataRequest.getPage() - 1), getManagerDataRequest.getPage() * getManagerDataRequest.getPageSize()),
                    result.size() % getManagerDataRequest.getPageSize() > 0 ? result.size() / getManagerDataRequest.getPageSize() + 1 : result.size() / getManagerDataRequest.getPageSize(), getManagerDataRequest.getPage());

        for (int i = 0; i < resultLater.size(); i++) {
            for (int j = 0; j < result.size(); j++) {
                if (resultLater.get(i).getGroupId().longValue() == result.get(j).getGroupId().longValue()) {
                    result.get(j).setRoiRat(resultLater.get(i).getRoi().doubleValue() == 0 ? null : (result.get(j).getRoi() - resultLater.get(i).getRoi()) / resultLater.get(i).getRoi());
                    result.get(j).setConvertRat(resultLater.get(i).getConvert().longValue() == 0 ? null : (result.get(j).getConvert() - resultLater.get(i).getConvert()) * 1.0 / resultLater.get(i).getConvert());
                    result.get(j).setCostRat(resultLater.get(i).getCost().doubleValue() == 0 ? null : (result.get(j).getCost() - resultLater.get(i).getCost()) / resultLater.get(i).getCost());
                    result.get(j).setConvert_costRat(resultLater.get(i).getConvert_cost().doubleValue() == 0 ? null : (result.get(j).getConvert_cost() - resultLater.get(i).getConvert_cost()) / resultLater.get(i).getConvert_cost());
                    result.get(j).setShowRat(resultLater.get(i).getShow().longValue() == 0 ? null : (result.get(j).getShow() - resultLater.get(i).getShow()) * 1.0 / resultLater.get(i).getShow());
                    break;
                }
            }
        }
        return new ManagerDataListPage(result.subList(getManagerDataRequest.getPageSize() * (getManagerDataRequest.getPage() - 1), getManagerDataRequest.getPage() * getManagerDataRequest.getPageSize()),
                result.size() % getManagerDataRequest.getPageSize() > 0 ? result.size() / getManagerDataRequest.getPageSize() + 1 : result.size() / getManagerDataRequest.getPageSize(), getManagerDataRequest.getPage());
    }


    @Override
    public List<GroupReportInfo> getManagerDataList(GetManagerDataRequest getManagerDataRequest) {
        List<GroupReportInfo> result = getManagerDataListTemplate(getManagerDataRequest);
        if (null == result)
            return null;

        int day = Tools.getDayFromdateToEndDate(getManagerDataRequest.getStart_date(), getManagerDataRequest.getEnd_date()) + 1;//左闭右闭，需要加1
        String startDate = Tools.getDatelaterDay(getManagerDataRequest.getStart_date(), day);
        String endDate = Tools.getDatelaterDay(getManagerDataRequest.getEnd_date(), day);

        getManagerDataRequest.setStart_date(startDate);
        getManagerDataRequest.setEnd_date(endDate);

        List<GroupReportInfo> resultLater = getManagerDataListTemplate(getManagerDataRequest);
        if (null == resultLater || resultLater.isEmpty())
            return result;

        for (int i = 0; i < resultLater.size(); i++) {
            for (int j = 0; j < result.size(); j++) {
                if (resultLater.get(i).getGroupId().longValue() == result.get(j).getGroupId().longValue()) {
                    result.get(j).setRoiRat(resultLater.get(i).getRoi().doubleValue() == 0 ? null : (result.get(j).getRoi() - resultLater.get(i).getRoi()) / resultLater.get(i).getRoi());
                    result.get(j).setConvertRat(resultLater.get(i).getConvert().longValue() == 0 ? null : (result.get(j).getConvert() - resultLater.get(i).getConvert()) * 1.0 / resultLater.get(i).getConvert());
                    result.get(j).setCostRat(resultLater.get(i).getCost().doubleValue() == 0 ? null : (result.get(j).getCost() - resultLater.get(i).getCost()) / resultLater.get(i).getCost());
                    result.get(j).setConvert_costRat(resultLater.get(i).getConvert_cost().doubleValue() == 0 ? null : (result.get(j).getConvert_cost() - resultLater.get(i).getConvert_cost()) / resultLater.get(i).getConvert_cost());
                    result.get(j).setShowRat(resultLater.get(i).getShow().longValue() == 0 ? null : (result.get(j).getShow() - resultLater.get(i).getShow()) * 1.0 / resultLater.get(i).getShow());
                    break;
                }
            }
        }

        Collections.sort(result, (o1, o2) -> new Double(o2.getRoi() - o1.getRoi()).intValue());
        return result.size() > 3 ? result.subList(0, 3) : result;
    }

    public List<GroupReportInfo> getManagerDataListTemplate(GetManagerDataRequest getManagerDataRequest) {
        QueryWrapper<YlyqGroupInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("advertiser_id", getManagerDataRequest.getAdvertiser_id());
        queryWrapper.orderByDesc("created_time");
        List<YlyqGroupInfo> list = iYlyqGroupInfoService.list(queryWrapper);
        if (null == list || list.isEmpty()) {
            return null;
        }
        Long[] groupIds = list.stream().map(YlyqGroupInfo::getGroupId).collect(Collectors.toList()).toArray(new Long[list.size()]);
        Map<Long, List<YlyqGroupInfo>> collectYlyqGroupInfo = list.stream().collect(Collectors.groupingBy(YlyqGroupInfo::getGroupId));

        GetReportGroupRequest groupRequest = new GetReportGroupRequest();
        groupRequest.setAdvertiser_id(getManagerDataRequest.getAdvertiser_id());
        groupRequest.setStart_date(getManagerDataRequest.getStart_date());
        groupRequest.setEnd_date(getManagerDataRequest.getEnd_date());
        groupRequest.setGroup_by(new String[]{"STAT_GROUP_BY_FIELD_ID"});
        GetReportGroupRequest.FilteringGetReportGroupRequest filteringGetReportGroupRequest = new GetReportGroupRequest.FilteringGetReportGroupRequest();
        filteringGetReportGroupRequest.setCampaign_ids(groupIds);
        filteringGetReportGroupRequest.setStatus("CAMPAIGN_STATUS_ENABLE");//
        groupRequest.setFiltering(filteringGetReportGroupRequest);
        OceanengineReportGroupInfo reportGroup = iOceanegineReportService.getReportGroup(groupRequest);
        if (null != reportGroup && null != reportGroup.getData() && null != reportGroup.getData().getList() && !reportGroup.getData().getList().isEmpty()) {
            List<OceanengineReportGroupInfo.DataBean.ListBean> listBeanList = reportGroup.getData().getList();
            Map<Long, List<OceanengineReportGroupInfo.DataBean.ListBean>> collectListReport = listBeanList.stream().collect(Collectors.groupingBy(OceanengineReportGroupInfo.DataBean.ListBean::getCampaign_id));
            for (YlyqGroupInfo temp : list) {
                //被用户在巨量手动删除的、暂停的组,顺便在YlyqGroupInfo表中也删除
                if (!collectListReport.containsKey(temp.getGroupId())) {
                    Map<String, Object> removeMap = new HashMap<>();
                    removeMap.put("advertiser_id", getManagerDataRequest.getAdvertiser_id());
                    removeMap.put("group_id", temp.getGroupId());
                    iYlyqGroupInfoService.removeByMap(removeMap);
                }
            }


            List<GroupReportInfo> resultGroupReportInfo = new ArrayList<>();
            for (int i = 0; i < listBeanList.size(); i++) {

                GroupReportInfo groupReportInfo = new GroupReportInfo();

                if (null == collectYlyqGroupInfo.get(listBeanList.get(i).getCampaign_id()) || collectYlyqGroupInfo.get(listBeanList.get(i).getCampaign_id()).isEmpty())
                    continue;

                BeanUtils.copyProperties(collectYlyqGroupInfo.get(listBeanList.get(i).getCampaign_id()).get(0), groupReportInfo);

                groupReportInfo.setGroupName(listBeanList.get(i).getCampaign_name());
                groupReportInfo.setCost(listBeanList.get(i).getCost());
                groupReportInfo.setShow(listBeanList.get(i).getShow());
                groupReportInfo.setConvert(listBeanList.get(i).getConvert());
                groupReportInfo.setConvert_cost(listBeanList.get(i).getConvert_cost());
                groupReportInfo.setCtr(listBeanList.get(i).getCtr());
                groupReportInfo.setConvert_rate(listBeanList.get(i).getConvert_rate());
                groupReportInfo.setRoi(groupReportInfo.getCost().doubleValue() == 0 ? 0 : groupReportInfo.getPriceForm() * groupReportInfo.getConvert() / groupReportInfo.getCost());
                resultGroupReportInfo.add(groupReportInfo);
            }
            return resultGroupReportInfo;
        } else {
//            先注释，因为有时网络访问异常，导致reportGroup==null，使得iYlyqGroupInfoService.removeByMap误删
            /**   //被用户在巨量手动删除的、暂停的组,顺便在YlyqGroupInfo表中也删除
             Map<String, Object> removeMap = new HashMap<>();
             removeMap.put("advertiser_id", getManagerDataRequest.getAdvertiser_id());
             iYlyqGroupInfoService.removeByMap(removeMap);
             **/
        }
        return null;
    }

    @Override
    public ManagerCore getManagerCore(GetManagerDataRequest getBalanceRequest) {
//        ROI:（（各广告组转化个数*各广告组转化价值）平方后/账户总消耗） *60
//        曝光：实际曝光/100
//        转化个数：实际转化个数/（日预算/预估转化成本）*100
//        素材质量：点击率*转化率*100/0.1%
//        出价竞争力：转化价值*80/转化成本
//
//        ROI得分>100，ROI得分=100
//        曝光得分>100，曝光得分=100
//        转化个数得分>100，转化个数得分=100
//        素材质量>100，素材质量=100
//        出价竞争力>100，出价竞争力=100
//
//        总分=ROI得分*0.6+曝光得分*0.2+转化个数得分*0.2
        GroupReportInfo groupReportInfo = getManagerDataTemplate(getBalanceRequest);
        if (groupReportInfo == null)
            return null;

        ManagerCore managerCore = new ManagerCore();
        managerCore.setROICore(Math.pow(groupReportInfo.getRoi(), 2) * 60 > 100 ? 100 : Math.pow(groupReportInfo.getRoi(), 2) * 60);
        managerCore.setShowCore(groupReportInfo.getShow() * 1.0 / 100 > 100 ? 100 : groupReportInfo.getShow() * 1.0 / 100);

        managerCore.setMaterialCore(groupReportInfo.getCtr() * groupReportInfo.getConvert_rate() * 1000 * 100 > 100 ? 100 : groupReportInfo.getCtr() * groupReportInfo.getConvert_rate() * 1000 * 100);
        managerCore.setCompetitiveCore(80 * groupReportInfo.getPriceForm() / groupReportInfo.getConvert_cost() > 100 ? 100 : 80 * groupReportInfo.getPriceForm() / groupReportInfo.getConvert_cost());

        QueryWrapper<YlyqPlanBidBudget> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("advertiser_id", getBalanceRequest.getAdvertiser_id());
        List<YlyqPlanBidBudget> listBid = iYlyqPlanBidBudgetService.list(queryWrapper);//统计的计划的预算和出价需是在智能启停投放中的,此处拿到的是凌晨智能启停时获取的昨日计划的预算和出价
        if (null == listBid || listBid.isEmpty()) {//如果没有获取到数据，则使用今天的出价和预算。但无论如何，都是拿智能投放的正在跑的计划做计算
//暂时不用，没有获取到数据时，就返回null
//            listBid=new ArrayList<>();
//
//            QueryWrapper<YlyqPlanStopStart> queryWrapperPlan = new QueryWrapper<>();
//            queryWrapperPlan.select("plan_id", "advertiser_id");
//            List<YlyqPlanStopStart> list = iYlyqPlanStopStartService.list(queryWrapperPlan);
//            Long[] planIds=new Long[list.size()];
//            for (int i = 0; i < list.size(); i++) {
//                planIds[i]=list.get(i).getPlanId();
//            }
//            //获取计划详情
//            GetPlanInfoRequest getPlanInfoRequest = new GetPlanInfoRequest();
//            getPlanInfoRequest.setAdvertiser_id(getBalanceRequest.getAdvertiser_id());
//            GetPlanInfoRequest.FilteringGetPlanInfoRequest filteringGetPlanInfoRequest = new GetPlanInfoRequest.FilteringGetPlanInfoRequest();
//            filteringGetPlanInfoRequest.setIds(planIds);
//            getPlanInfoRequest.setFiltering(filteringGetPlanInfoRequest);
//            OceanenginePlanInfo planInfo = iOceaneginePlanService.getPlan(getPlanInfoRequest);
//
//
//            List<OceanenginePlanInfo.DataBean.ListBean> planInfolist = planInfo.getData().getList();
//            for (OceanenginePlanInfo.DataBean.ListBean temp:planInfolist) {
//                YlyqPlanBidBudget ylyqPlanBidBudget=new YlyqPlanBidBudget(temp.getAdvertiser_id(),temp.getCampaign_id(),temp.getId(),temp.getBudget(),temp.getBid());
//                listBid.add(ylyqPlanBidBudget);
//            }
            return managerCore;
        }

        double convertRat = 0;
        for (YlyqPlanBidBudget temp : listBid) {
            convertRat += temp.getBudget() / temp.getBid();
        }
        convertRat = convertRat / listBid.size();//取平均数

        managerCore.setConvertCore(groupReportInfo.getConvert() * 100 / convertRat > 100 ? 100 : groupReportInfo.getConvert() * 100 / convertRat);

        managerCore.setCoreResult(managerCore.getROICore() * 0.6 + managerCore.getShowCore() * 0.1 + managerCore.getConvertCore() * 0.1 + managerCore.getMaterialCore() * 0.1 + managerCore.getCompetitiveCore() * 0.1);


        if (managerCore.getCoreResult() < 60) {
            managerCore.setScoreEvaluation("不要气馁！");
            managerCore.setAdvice("建议耐心等待一下，投放效果有很大的上升空间，同时建议追加投入，确保余额充足，以免因为余额不足影响投放效果");
        } else if (managerCore.getCoreResult() > 80) {
            managerCore.setScoreEvaluation("真棒！");
            managerCore.setAdvice("投放效果各项分值指标都表现不错，建议留意账户余额，确保余额充足，以防影响投放效果。");
        } else {
            managerCore.setScoreEvaluation("平稳增长，不错！");
            String[] doc = {"计划平稳增长中，静待其表现...", "建议耐心等待一下，观望一段时间很大概率会有意想不到的效果哦。"};
            int index = (int) (Math.random() * doc.length);
            String random = doc[index];
            managerCore.setAdvice(random);
        }
        return managerCore;
    }

    @Override
    public CanUseManage canUseManage(CanUseManageRequest issetAccountRequest) {
        GetPlanInfoRequest getPlanInfoRequest = new GetPlanInfoRequest();
        getPlanInfoRequest.setAdvertiser_id(issetAccountRequest.getAdvertiser_id());
        GetPlanInfoRequest.FilteringGetPlanInfoRequest filteringGetPlanInfoRequest = new GetPlanInfoRequest.FilteringGetPlanInfoRequest();
        filteringGetPlanInfoRequest.setStatus("AD_STATUS_DELIVERY_OK");
//        filteringGetPlanInfoRequest.setStatus(("AD_STATUS_DELIVERY_OK") && !planDetail.getStatus().equals("AD_STATUS_BALANCE_EXCEED"));
        getPlanInfoRequest.setFiltering(filteringGetPlanInfoRequest);
        OceanenginePlanInfo plan = iOceaneginePlanService.getPlan(getPlanInfoRequest);
        if (plan != null && plan.getCode() == AccountConstant.SUCCESS) {
            if (plan.getData() != null)
                if (plan.getData().getList().size() > 0)
                    return new CanUseManage(1);
                else
                    return new CanUseManage(0);
        }

        return null;
    }

}
